#pragma once

/*
 * TCP 服务器会话管理类
 */

#include <async_simple/coro/Lazy.h>

#include <boost/asio.hpp>
#include <memory>

#include "KVMiddleware.h"

using boost::asio::ip::tcp;

class Session : public std::enable_shared_from_this<Session> {
public:
    explicit Session(tcp::socket socket,
                     std::shared_ptr<KVMiddleware> &kv_middleware)
        : socket_(std::move(socket)),
          heartbeat_timer_(socket.get_executor()),
          kv_middleware_(kv_middleware) {}

    // 开始会话
    void start();

private:
    // 状态机模式管理循环
    boost::asio::awaitable<void> handle();

    // 读取消息头（判断是否是心跳包）
    boost::asio::awaitable<void> read_header();

    // 读取消息长度
    boost::asio::awaitable<void> read_length();

    // 读取消息体
    boost::asio::awaitable<void> read_body();

    // 异步写数据
    boost::asio::awaitable<void> write(const std::string &message);

    // 重置心跳包计时器
    void reset_heartbeat_timer();


    // 客户端socket
    tcp::socket socket_;
    // 心跳包计时器
    boost::asio::steady_timer heartbeat_timer_;
    const std::chrono::seconds heartbeat_interval_ = std::chrono::seconds(60);
    // 消息头（判断是否是心跳包）
    bool header = false;
    // 消息长度
    uint32_t message_length = 0;
    // 消息内容缓冲区
    std::vector<char> buffer_;
    enum class State {
        ReadHeader,
        ReadLength,
        ReadBody,
        Closed
    };
    // 当前状态
    State state_ = State::ReadHeader;

    // 中间件实例
    std::shared_ptr<KVMiddleware> kv_middleware_;
};